//: typeinfo/toys/ToyTest.java
// Testing class Class.
package typeinfo.toys;

import static net.mindview.util.Print.*;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

interface HasBatteries {
}

interface Waterproof {
}

interface Shoots {
}

interface Dowmy {
}

class Toy {
	// Comment out the following default constructor
	// to see NoSuchMethodError from (*1*)
	// Toy() {
	// }
	//
	// Toy(int i) {
	// }

	public Toy() {
	}

	public Toy(int i) {
	}
}

class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots, Dowmy {
	FancyToy() {
		super(1);
	}
}

public class ToyTest {
	static void printInfo(Class cc) {
		print("Class name: " + cc.getName() + " is interface? ["
				+ cc.isInterface() + "]");
		print("Simple name: " + cc.getSimpleName());
		print("Canonical name : " + cc.getCanonicalName());
	}

	public static Toy getToy() {
		Class c = null;
		try {
			c = Class.forName("typeinfo.toys.Toy");
		} catch (ClassNotFoundException e) {
			print("Can't find FancyToy");
			System.exit(1);
		}
		Constructor[] constructors = c.getConstructors();
		for (int i = 0; i < constructors.length; i++) {
			if (constructors[i].getParameterTypes().length == 1) {
				if (constructors[i].getParameterTypes()[0] == int.class) {
					try {
						return (Toy) constructors[i]
								.newInstance(new Object[] { 1 });
					} catch (InstantiationException | IllegalAccessException
							| IllegalArgumentException
							| InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
		return null;
	}

	public static void main(String[] args) {
		Class c = null;
		try {
			c = Class.forName("typeinfo.toys.FancyToy");
		} catch (ClassNotFoundException e) {
			print("Can't find FancyToy");
			System.exit(1);
		}

		System.out.println("###############");
		Toy toy = getToy();
		if (toy == null) {
			System.out.println("null");
		} else {
			System.out.println(toy);
		}
		System.out.println("###############");

		printInfo(c);
		for (Class face : c.getInterfaces())
			printInfo(face);
		Class up = c.getSuperclass();
		Object obj = null;
		try {
			// Requires default constructor:
			obj = up.newInstance();
		} catch (InstantiationException e) {
			print("Cannot instantiate");
			System.exit(1);
		} catch (IllegalAccessException e) {
			print("Cannot access");
			System.exit(1);
		}
		printInfo(obj.getClass());
	}
} /*
 * Output: Class name: typeinfo.toys.FancyToy is interface? [false] Simple name:
 * FancyToy Canonical name : typeinfo.toys.FancyToy Class name:
 * typeinfo.toys.HasBatteries is interface? [true] Simple name: HasBatteries
 * Canonical name : typeinfo.toys.HasBatteries Class name:
 * typeinfo.toys.Waterproof is interface? [true] Simple name: Waterproof
 * Canonical name : typeinfo.toys.Waterproof Class name: typeinfo.toys.Shoots is
 * interface? [true] Simple name: Shoots Canonical name : typeinfo.toys.Shoots
 * Class name: typeinfo.toys.Toy is interface? [false] Simple name: Toy
 * Canonical name : typeinfo.toys.Toy
 */// :~
